<template>
    <div class="work-flow">
        <div class="work-flow-main"
            :style="'width: '+ attr.width +'px; height: '+ attr.height +'px;'"
        >
            <canvas class="work-flow-cavs" id="work_flow_cavs"></canvas>
            <ul class="work-flow-list">
                <li
                    v-for="(node, index) in nodeList"
                    :class="getNodeClass(node)"
                    :style="'top: '+ node.ycoordinate +'px; left: '+ node.xcoordinate +'px;'"
                    :key="index">
                    <h3 class="wkfl-item-audr"
                        :style="'top: '+ node.auditorTop +'px;'">
                        <p class="wfim-audr-text">{{ node.nodeName }}</p>
                    </h3>
                    <div class="wkfl-item-node"
                        @mouseenter="nodeApprOpinShow(node)"
                        @mouseleave="nodeApprOpinHide()"
                    ><i class="wfim-node-dot"></i></div>
                    <h4 class="wkfl-item-type"
                        v-show="!!node.branchType"
                        :style="'bottom: '+ node.branchBottom +'px;'"
                    >{{ node.branchType }}</h4>
                </li>
            </ul>
            <div class="work-flow-opin"
                v-show="nodeOpin.show"
                :style="'top: '+ nodeOpin.posY +'px; left: '+ nodeOpin.posX +'px;'">
                <div class="wkfl-opin-main">
                    <h3 class="wkfl-opin-title">{{ nodeOpin.nodeName }}<span>({{ nodeOpin.nodeDesc }})</span></h3>
                    <p class="wkfl-opin-signr" v-show="!nodeOpin.signOpin && nodeOpin.signName">{{ nodeOpin.signLabel }}：{{ nodeOpin.signName }}</p>
                    <p class="wkfl-opin-start" v-show="nodeOpin.startDate">发起时间：{{ nodeOpin.startDate }}</p>
                    <p class="wkfl-opin-ctnt" v-show="nodeOpin.signOpin">{{ nodeOpin.signOpin }}</p>
                    <div class="wkfl-opin-info" v-show="nodeOpin.signDate && nodeOpin.signName">签批时间：<span class="date">{{ nodeOpin.signDate }}</span>签批人：<span class="name">{{ nodeOpin.signName }}</span></div>
                </div>
                <span class="wkfl-opin-arrow top"
                    :style="'left: '+ nodeOpin.arrowPosX +'px;'"
                ></span>
                <span class="wkfl-opin-arrow bottom"
                    :style="'left: '+ nodeOpin.arrowPosX +'px;'"
                ></span>
            </div>
        </div>
        <Modal
            class="work-flow-dlog"
            v-model="selectHandlerShow"
            title="选择办理人"
            width="500"
            @on-ok="selectHandlerOk"
            @on-cancel="selectHandlerCancel">
            <ul class="wkfl-hdlr-list">
                <li class="wkfl-hdlr-item"
                    v-for="(handler, index) in selectHandlerList"
                    :key="index">
                    <a class="wfhd-item-sel"
                        title="选择办理人"
                        v-show="handler.editFlag || nodeBackSubmit"
                        @click="selectHandler(handler)"></a>
                    <label class="wfhd-item-name">{{ handler.nodeName }}：</label>
                    <input type="text" class="wfhd-item-hdlr" :value="handler.handleUserName" placeholder="请选择办理人" readonly>
                </li>
            </ul>
            <div class="wkfl-hdlr-oper" slot="footer">
                <a class="cancel" @click="selectHandlerCancel">取消</a>
                <a class="save" @click="selectHandlerOk">保存</a>
            </div>
        </Modal>
        <orgTree
            :visible="orgTreeVisible"
            :option="{deptFlag: false, userFlag: true, singleFlag: true}"
            :result="orgTreeHandlerList"
            @update:visible="orgTreeVisible = false"
            @on-save="selectHandlerSave"
        ></orgTree>
        <Modal
            class="work-flow-dlog"
            v-model="nodeRemindShow"
            title="提交节点确认"
            width="420"
            @on-ok="nodeRemindOk"
            @on-cancel="nodeRemindCancel">
            <p class="wkfl-hdlr-end">{{ nodeRemindMsgCur }}</p>
            <div class="wkfl-hdlr-oper" slot="footer">
                <a class="cancel" @click="nodeRemindCancel">取消</a>
                <a class="save" @click="nodeRemindOk">确定</a>
            </div>
        </Modal>
    </div>
</template>
<script>
import orgTree from '../../orgtree/OrgTree'
import workFlowApi from '../../../api/workflow/workFlow.js'

export default {
    name: "workFlow",
    props: {
        workFlowData:{
            type:Object,
            default:function () {
                return []
            }
        },
        showDetails:{
            type:Boolean,
            default:function () {
                return false
            }
        },
        infoId: {
            type: String,
            default: ''
        },
        tmplId: {
            type: String,
            default: ''
        },
        handlerMap: {
            type: Object,
            default: function(){
                return {};
            }
        },
        startSubmit: {
            type: Object,
            default: function(){
                return {
                    start: false
                };
            }
        },
        passData: {
            type: Object,
            default: function(){
                return {
                    start: false
                };
            }
        }
    },
    data(){
        return {
            nodeIdMap: {},
            nodeHorzPos: {},
            nodeCur: null,
            nodeStart: null,
            nodeBackSubmit: false,
            nodeBackHandler: [],
            nodeBackList: [],
            nodeOpin: {
                show: false,
                posX: 0,
                posY: 0,
                arrowPosX: 0,
                nodeName: '',
                nodeDesc: '',
                signOpin: '',
                signLabel: '',
                signName: '',
                signDate: '',
                startDate: ''
            },
            nodeList: [],
            lineList: [],
            cavsObj: null,
            cavsWidth: 0,
            cavsHeight: 0,
            ctx2D: null,
            attr: {
                width: 800,
                height: 300
            },
            selectHandlerShow: false,
            selectHandlerCur: null,
            selectHandlerList: null,
            orgTreeVisible: false,
            orgTreeHandlerList: [],
            nodeRemindShow: false,
            nodeRemindMsgCur: '',
            nodeRemindMsgMap: {
                'back': '您确定要提交给||？',
                'end': '您确定要提交到结束节点？'
            },
            drivenItem: null
        };
    },
    watch: {
        infoId(val){
            if(val){
                this.init();
            }
        },
        workFlowData(val){
            if(val){
                this.init();
            }
        },
        startSubmit(obj){
            if(obj.start){
                this.dealStartSubmit();
            }
        },
        passData(obj){
            if(obj.start){
                this.provideNodeData();
            }
        }
    },
    mounted(){
        this.cavsObj = document.getElementById('work_flow_cavs');
        if(this.cavsObj && this.cavsObj.getContext){
            this.ctx2D = this.cavsObj.getContext('2d');
        }
        this.init();
    },
    methods: {
        init(){
            this.nodeCur = null;
            this.nodeStart = null;
            this.nodeBackSubmit = false;
            this.nodeBackHandler = [];
            this.nodeBackList = [];
            if(this.infoId){
                workFlowApi.getWorkFlowDetailByInfoId(this.infoId)
                    .then(res => {
                        this.parseData(res.data);
                    })
                    .catch(error => {
                        console.log(error);
                    });
            }else if(this.tmplId){
                workFlowApi.getWorkFlowDetailByTemplateId(this.tmplId)
                    .then(res => {
                        this.parseData(res.data);
                    })
                    .catch(error => {
                        console.log(error);
                    });
            }else if(this.showDetails){
                this.parseData(this.workFlowData);
            }else{
                return false;
            }
        },
        getNodeClass(node){
            var _class = {
                'work-flow-item ': true
            };
            if(node){
                _class['start'] = node.isStart;
                _class['gene'] = node.isGene;
                _class['end'] = node.isEnd;
                _class['active'] = node.isActive;
                _class['is-pass'] = node.isPass;
                _class['not-pass'] = node.notPass;
                _class['not-start'] = node.notStart;
                _class['not-impl'] = node.notImpl;
            }
            return _class;
        },
        parseData(data){
            if(!data || !(data instanceof Object) || !(data.wfNodeItemList instanceof Array) || data.wfNodeItemList.length == 0){
                return false;
            }
            let _self = this,
                _nodeIdMap = this.nodeIdMap,
                _nodeList = data.wfNodeItemList,
                _userCur = this.$store.state.currentUser;
            this.attr = {
                'wfInfoId': data.wfInfoId || '',
                'wfBizDictId': data.wfBizDictId,
                'wfName': data.wfName,
                'bizId': data.bizId,
                'createUserId': data.createUserId,
                'createUserName': data.createUserName,
                'wfDesc': data.wfDesc,
                'updateTime': data.updateTime,
                'createTime': data.createTime,
                'width': !isNaN(data.width) ? data.width : 800,
                'height': !isNaN(data.height) ? data.height : 300
            };
            this.cavsObj.width = this.attr.width;
            this.cavsObj.height = this.attr.height;
            this.lineList = data.wfNodeRelItemList;
            _nodeList.forEach((node, index) => {
                let _top = 0;
                node.parentNodeIdList = [];
                node.subNodeIdList = [];
                if(node.nodeType == '0'){
                    node.isStart = true;
                    _self.nodeStart = node;
                }else{
                    node.isStart = false;
                }
                node.isGene = node.nodeType == '1';
                node.isEnd = node.nodeType == '2';
                node.notStart = node.state == '0';
                node.notImpl = node.state == '5';
                if(node.state == '1' && !_self.nodeCur){
                    if(node.handleUserId){
                        if(_userCur && _userCur.userId && node.handleUserId == _userCur.userId){
                            node.isActive = true;
                            _self.nodeCur = node;
                        }else{
                            node.isActive = false;
                        }
                    }else{
                        node.isActive = true;
                        _self.nodeCur = node;
                    }
                }else{
                    node.isActive = false;
                }
                node.isPass = node.state == '2';
                node.notPass = '3,4'.indexOf(node.state) > -1;
                if(node.state == '4'){
                    _self.nodeBackList.push(node);
                }
                node.noBorder = node.isStart || node.isEnd || (!node.isActive && !node.isPass && !node.notPass);
                if(node.isStart){
                    _self.nodeHorzPos.xcoordinate = node.xcoordinate;
                    _self.nodeHorzPos.ycoordinate = node.ycoordinate;
                }
                if(node.isStart || node.isEnd){
                    _top = 22;
                }else{
                    if(node.nodeName.length > 18){
                        node.nodeName = node.nodeName.substring(0, 15) + '...';
                    }
                    _top = Math.ceil(node.nodeName.length/6)*16 + 6 + 3;
                    if(node.isActive){
                        _top += 2 + 8;
                    }
                    if(node.noBorder){
                        _top -= 6;
                    }
                }
                node.auditorTop = -_top;
                if(node.noBorder){
                    node.branchBottom = -19;
                }else{
                    node.branchBottom = -25;
                }
                _nodeIdMap[node.nodeId] = node;
            });
            this.nodeList = _nodeList;
            //绘制连接线
            this.drawNodeConnLines();
        },
        drawNodeConnLines(){
            let _self = this,
                _nodeIdMap = this.nodeIdMap,
                _lineList = this.lineList,
                _ctx2D = this.ctx2D,
                _posList = [];
            if(_lineList.length == 0 || !_ctx2D){
                return false;
            }
            _ctx2D.strokeStyle = '#8AD737';
            _ctx2D.lineWidth = 2;
            //判断各节点子节点个数
            _lineList.forEach((line, index) => {
                if(!line.parentNodeId || line.parentNodeId == '-1'){
                    return true;
                }
                let _from = _nodeIdMap[line.parentNodeId],
                    _to = _nodeIdMap[line.nodeId];
                if(_from && _to){
                    _from.subNodeIdList.push(line.nodeId);
                    _to.parentNodeIdList.push(line.parentNodeId);
                }
            });
            //计算各节点坐标
            _lineList.forEach((line, index) => {
                if(!line.parentNodeId || line.parentNodeId == '-1'){
                    return true;
                }
                let _from = _nodeIdMap[line.parentNodeId],
                    _to = _nodeIdMap[line.nodeId];
                if(_from && _from.parentNodeIdList.length == 1 && _to){
                    let _parent = _nodeIdMap[_from.parentNodeIdList[0]];
                    if(_parent && _parent.precondition == '2' && _parent.subNodeIdList.length == 1 && _from.subNodeIdList.length == 1 && _to.parentNodeIdList.length == 1){
                        _parent.solidFlag = true;
                        //_from.ycoordinate = _self.nodeHorzPos.ycoordinate;
                        _from.solidFlag = true;
                    }
                }
            });
            //计算连接线起止坐标
            _lineList.forEach((line, index) => {
                if(!line.parentNodeId || line.parentNodeId == '-1'){
                    return true;
                }
                let _from = _nodeIdMap[line.parentNodeId],
                    _to = _nodeIdMap[line.nodeId],
                    _pos = _self.getLinePosition(_from, _to);
                if(_pos){
                    if(!_from.solidFlag && _from.precondition == '2'){
                        _pos.lineDash = [6, 6];
                    }else if(!_from.solidFlag && _from.precondition == '1'){
                        _pos.lineDash = [2, 4, 12, 4];
                    }else{
                        _pos.lineDash = [5, 0];
                    }
                    _pos.strokeStyle = '1,2,3,4'.indexOf(line.state) == -1 ? '#CACDCC' : '#8AD737';
                    _posList.push(_pos);
                }
            });
            //绘制连接线
            _posList.forEach((pos, index) => {
                _ctx2D.beginPath();
                _ctx2D.setLineDash(pos.lineDash);
                _ctx2D.strokeStyle = pos.strokeStyle;
                _ctx2D.moveTo(pos.startX, pos.startY);
                _ctx2D.lineTo(pos.endX, pos.endY);
                _ctx2D.closePath();
                _ctx2D.stroke();
            });
            this.setNodeBranchType();
        },
        getLinePosition(from, to){
            if(!from || !to){
                return false;
            }
            let _rad = 0,
                _hypt = 0,
                _startX = 0,
                _startY = 0,
                _endX = 0,
                _endY = 0;
            if(from.xcoordinate < to.xcoordinate){
                if(from.ycoordinate < to.ycoordinate){
                    _rad = Math.atan((to.ycoordinate - from.ycoordinate)/(to.xcoordinate - from.xcoordinate));
                    if(from.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _startX = from.xcoordinate + 15 + parseInt(_hypt*Math.cos(_rad));
                    _startY = from.ycoordinate + 15 + parseInt(_hypt*Math.sin(_rad));
                    if(to.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _endX = to.xcoordinate + 15 - parseInt(_hypt*Math.cos(_rad));
                    _endY = to.ycoordinate + 15 - parseInt(_hypt*Math.sin(_rad));
                }else if(from.ycoordinate == to.ycoordinate){
                    _startX = from.xcoordinate + 30;
                    if(!from.noBorder){
                        _startX += 6;
                    }
                    _startY = from.ycoordinate + 15;
                    _endX = to.xcoordinate;
                    if(!to.noBorder){
                        _endX -= 6;
                    }
                    _endY = to.ycoordinate + 15;
                }else{
                    _rad = Math.atan((from.ycoordinate - to.ycoordinate)/(to.xcoordinate - from.xcoordinate));
                    if(from.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _startX = from.xcoordinate + 15 + parseInt(_hypt*Math.cos(_rad));
                    _startY = from.ycoordinate + 15 - parseInt(_hypt*Math.sin(_rad));
                    if(to.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _endX = to.xcoordinate + 15 - parseInt(_hypt*Math.cos(_rad));
                    _endY = to.ycoordinate + 15 + parseInt(_hypt*Math.sin(_rad));
                }
            }else if(from.xcoordinate == to.xcoordinate){
                _startX = from.xcoordinate + 15;
                _endX = to.xcoordinate + 15;
                if(from.ycoordinate < to.ycoordinate){
                    _startY = from.ycoordinate + 30;
                    if(!from.noBorde){
                        _startY += 6;
                    }
                    _endY = to.ycoordinate;
                    if(!to.noBorder){
                        _endY -= 6;
                    }
                }else{
                    _startY = from.ycoordinate;
                    if(!from.noBorde){
                        _startY -= 6;
                    }
                    _endY = to.ycoordinate + 30;
                    if(!to.noBorder){
                        _endY += 6;
                    }
                }
            }else{
                if(from.ycoordinate < to.ycoordinate){
                    _rad = Math.atan((to.ycoordinate - from.ycoordinate)/(from.xcoordinate - to.xcoordinate));
                    if(from.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _startX = from.xcoordinate + 15 - parseInt(_hypt*Math.cos(_rad));
                    _startY = from.ycoordinate + 15 + parseInt(_hypt*Math.sin(_rad));
                    if(to.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _endX = to.xcoordinate + 15 + parseInt(_hypt*Math.cos(_rad));
                    _endY = to.ycoordinate + 15 - parseInt(_hypt*Math.sin(_rad));
                }else if(from.ycoordinate == to.ycoordinate){
                    _startX = from.xcoordinate;
                    if(!from.noBorder){
                        _startX -= 6;
                    }
                    _startY = from.ycoordinate + 15;
                    _endX = to.xcoordinate + 30;
                    if(!to.noBorder){
                        _endX += 6;
                    }
                    _endY = to.ycoordinate + 15;
                }else{
                    _rad = Math.atan((from.ycoordinate - to.ycoordinate)/(from.xcoordinate - to.xcoordinate));
                    if(from.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _startX = from.xcoordinate + 15 - parseInt(_hypt*Math.cos(_rad));
                    _startY = from.ycoordinate + 15 - parseInt(_hypt*Math.sin(_rad));
                    if(to.noBorder){
                        _hypt = 15;
                    }else{
                        _hypt = 21;
                    }
                    _endX = to.xcoordinate + 15 + parseInt(_hypt*Math.cos(_rad));
                    _endY = to.ycoordinate + 15 + parseInt(_hypt*Math.sin(_rad));
                }
            }
            return {"startX": _startX, "startY": _startY, "endX": _endX, "endY": _endY};
        },
        setNodeBranchType(){
            let _nodeList = this.nodeList;
            _nodeList.forEach((node, index) => {
                if(node.nodeType == '1' && node.subNodeIdList.length > 1){
                    if(node.precondition == '1'){
                        node.branchType = '鉴别';
                    }else if(node.precondition == '2'){
                        node.branchType = '唯一';
                    }else{
                        node.branchType = '并发';
                    }
                }
            });
        },
        dealStartSubmit(){
            let _self = this,
                _nodeCur = this.nodeCur,
                _nodeStart = this.nodeStart,
                _nodeBackList = this.nodeBackList,
                _nodeIdMap = this.nodeIdMap,
                _userCur = this.$store.state.currentUser,
                _errorStr = '',
                _subNodeIdList = null,
                _drivenItem = null,
                _drivenList = [];
            if(!_nodeCur){
                this.$emit('on-error', {state: '1', msg: '未找到待办节点！'});
                return false;
            }else{
                _subNodeIdList = _nodeCur.subNodeIdList;
                _drivenItem = {
                    "currentNodeHandleItem": {
                        "approvalOpition": _nodeCur.approvalOpition || '',
                        "nodeId": _nodeCur.nodeId,
                        "state": "1",
                        "wfInfoId": _nodeCur.wfInfoId || ''
                    },
                    "nextNodeDrivenListItem": {
                        "nextNodeDrivenList": []
                    },
                    "wfInfoId": this.attr.wfInfoId
                };
            }
            if(_nodeStart && _nodeStart == _nodeCur && _nodeBackList.length > 0){
                let _nodeBackHandler = [];
                _nodeBackList.forEach((node, index) => {
                    _nodeBackHandler.push(node.handleUserName);
                    _drivenList.push({
                        "handleUserId": node.handleUserId,
                        "handleUserName": node.handleUserName,
                        "nodeId": node.nodeId,
                        "nodeType": node.nodeType,
                        "wfInfoId": node.wfInfoId || ''
                    });
                });
                this.nodeBackHandler = _nodeBackHandler;
            }else{
                if(!_subNodeIdList || !(_subNodeIdList instanceof Array) || _subNodeIdList.length == 0){
                    this.$emit('on-error', {state: '1', msg: '待办节点没有子节点'});
                    return false;
                }
                if("1,2".indexOf(_nodeCur.precondition) > -1){
                    _subNodeIdList.forEach((id, index) => {
                        let _node = _nodeIdMap[id],
                            _condList = null;
                        if(_node){
                            _condList = JSON.parse(_node.postcondition).postposition;
                            if(_condList instanceof Array && _condList.length > 0){
                                let _operFlag = false,
                                    _operStr = [];
                                _condList.forEach((cond, condIndex) => {
                                    let _value = _self.$el.getAttribute(cond.targetColumnName);
                                    if(_value != null){
                                        if(cond.decideCondition == 'equal'){
                                            _operStr.push('\''+ _value +'\'');
                                            _operStr.push('==');
                                            _operStr.push('\''+ cond.decideValue +'\'');
                                        }else if(cond.decideCondition == '!equal'){
                                            _operStr.push('\''+ _value +'\'');
                                            _operStr.push('!=');
                                            _operStr.push('\''+ cond.decideValue +'\'');
                                        }else if(cond.decideCondition.indexOf('index:') > -1){
                                            let _index = parseInt(cond.decideCondition.split(':')[1]);
                                            if(!isNaN(_index)){
                                                _value = (_value + '').charAt(_index);
                                                _value = !_value ? '-' : _value;
                                                _operStr.push('\''+ _value +'\'');
                                                _operStr.push('==');
                                                _operStr.push('\''+ cond.decideValue +'\'');
                                            }else{
                                                _operStr.push('false');
                                            }
                                        }else{
                                            _operStr.push(_value);
                                            _operStr.push(cond.decideCondition);
                                            _operStr.push(cond.decideValue);
                                        }
                                        if(cond.logicOperation){
                                            _operStr.push(cond.logicOperation);
                                        }
                                    }else{
                                        _operStr.push('false');
                                    }
                                });
                                try{
                                    _operFlag = eval(_operStr.join(' '));
                                }catch(e){
                                    console.log(e);
                                }
                                if(_operFlag){
                                    _drivenList.push({
                                        "handleUserId": _node.handleUserId,
                                        "handleUserName": _node.handleUserName,
                                        "nodeId": _node.nodeId,
                                        "nodeType": _node.nodeType,
                                        "wfInfoId": _node.wfInfoId || ''
                                    });
                                }
                            }else{
                                if(_nodeCur.precondition == '1'){
                                    _drivenList.push({
                                        "handleUserId": _node.handleUserId,
                                        "handleUserName": _node.handleUserName,
                                        "nodeId": _node.nodeId,
                                        "nodeType": _node.nodeType,
                                        "wfInfoId": _node.wfInfoId || ''
                                    });
                                }
                            }
                        }
                    });
                }else{
                    _subNodeIdList.forEach((id, index) => {
                        let _node = _nodeIdMap[id];
                        if(_node){
                            _drivenList.push({
                                "handleUserId": _node.handleUserId,
                                "handleUserName": _node.handleUserName,
                                "nodeId": _node.nodeId,
                                "nodeType": _node.nodeType,
                                "wfInfoId": _node.wfInfoId || ''
                            });
                        }
                    });
                }
            }
            if(_drivenList.length == 0){
                this.$emit('on-error', {state: '1', msg: '没有符合条件的下级节点！'});
            }else{
                _drivenItem.nextNodeDrivenListItem.nextNodeDrivenList = _drivenList;
                this.drivenItem = _drivenItem;
                this.selectHandlerUser();
            }
        },
        selectHandlerUser(){
            let _handlerMap = this.handlerMap,
                _nodeIdMap = this.nodeIdMap,
                _nodeCur = this.nodeCur,
                _nodeBackHandler = this.nodeBackHandler,
                _drivenList = this.drivenItem.nextNodeDrivenListItem.nextNodeDrivenList,
                _nodeEnd = null,
                _handlerList = [];
            if(_nodeBackHandler instanceof Array && _nodeBackHandler.length > 0){
                this.nodeBackSubmit = true;
                // this.nodeRemind('back');
                // return false;
            }else{
                this.nodeBackSubmit = false;
            }
            _drivenList.forEach((item, index) => {
                let _handler = _handlerMap[item.nodeId],
                    _node = _nodeIdMap[item.nodeId];
                if(_node){
                    if(!_node.isEnd){
                        _handlerList.push({
                            nodeId: _node.nodeId,
                            nodeName: _node.nodeName,
                            handleUserId: _handler ? _handler.id : (_node.handleUserId ? _node.handleUserId : ''),
                            handleUserName: _handler ? _handler.name : (_node.handleUserName ? _node.handleUserName : ''),
                            editFlag:  !_handler && !_node.handleUserId
                        });
                    }else{
                        _nodeEnd = _node;
                    }
                }
            });
            if(_handlerList.length > 0){
                this.selectHandlerList = _handlerList;
                this.selectHandlerShow = true;
            }else if(_nodeEnd){
                this.selectHandlerList = [];
                this.nodeRemind('end');
            }else{
                this.$emit('on-error', {state: '1', msg: '没有符合条件的下级节点！'});
            }
        },
        checkHandleUser(){
            let _nodeCur = this.nodeCur,
                _nodeIdMap = this.nodeIdMap,
                _drivenList = this.drivenItem.nextNodeDrivenListItem.nextNodeDrivenList,
                _handlerFlag = false,
                _checkFlag = true;
            _drivenList.forEach((item, index) => {
                let _node = _nodeIdMap[item.nodeId];
                if(_node && !_node.isEnd){
                    if(!_node.handleUserId || !_node.handleUserName){
                        _checkFlag = false;
                    }else{
                        _handlerFlag = _nodeCur.precondition == '1' ? true : false;
                    }
                }
            });
            return _handlerFlag || _checkFlag;
        },
        updateDrivenItem(){
            let _handler = null,
                _node = null,
                _nodeIdMap = this.nodeIdMap,
                _handlerList = this.selectHandlerList,
                _drivenList = this.drivenItem.nextNodeDrivenListItem.nextNodeDrivenList;
            if(_handlerList.length == 0){
                return false;
            }
            for(let i = 0, _len = _handlerList.length; i < _len; i++){
                _handler = _handlerList[i];
                _node = _nodeIdMap[_handler.nodeId];
                if(_handler && _node){
                    _drivenList.forEach((item, index) => {
                        if(item.nodeId == _handler.nodeId){
                            item.handleUserId = _node.handleUserId = _handler.handleUserId;
                            item.handleUserName = _node.handleUserName = _handler.handleUserName;
                        }
                    });
                }
            }
        },
        selectHandler(handler){
            if(!handler){
                return false;
            }
            this.selectHandlerCur = handler;
            if(handler.handleUserId && handler.handleUserName){
                this.orgTreeHandlerList.push({
                    id: handler.handleUserId,
                    name: handler.handleUserName,
                    type: "user"
                });
            }else{
                this.orgTreeHandlerList = [];
            }
            this.orgTreeVisible = true;
        },
        selectHandlerOk(){
            this.updateDrivenItem();
            if(!this.checkHandleUser()){
                this.$Message.error('您还有节点未选择执行人！');
            }else{
                this.selectHandlerShow = false;
                this.dispatchSubmit();
            }
        },
        selectHandlerCancel(){
            this.selectHandlerShow = false;
            this.$emit('on-error', {state: '0', msg: '取消选择执行人'});
        },
        selectHandlerSave(seledList){
            let _handler = this.selectHandlerCur;
            if(_handler && seledList instanceof Array && seledList.length > 0){
                _handler.handleUserId = seledList[0].id;
                _handler.handleUserName = seledList[0].name;
            }
        },
        nodeRemind(type = 'end'){
            let _msg = this.nodeRemindMsgMap[type];
            if(type == 'back'){
                _msg = _msg.replace('||', this.nodeBackHandler.join('、'));
            }
            this.nodeRemindMsgCur = _msg;
            this.nodeRemindShow =  true;
        },
        nodeRemindOk(){
            this.nodeRemindShow = false;
            this.dispatchSubmit();
        },
        nodeRemindCancel(){
            this.nodeRemindShow = false;
            this.$emit('on-error', {state: '0', msg: '取消提交到下级节点'});
        },
        dispatchSubmit(){
            if(this.drivenItem){
                this.$emit('on-submit', this.drivenItem);
            }
        },
        provideNodeData(){
            this.$emit('on-data', this.nodeList);
        },
        nodeApprOpinShow(node){
            if(!node || node.isEnd){
                return false;
            }
            let _attr = this.attr,
                _nodeOpin = this.nodeOpin;
            _nodeOpin.nodeName = node.nodeName;
            _nodeOpin.nodeDesc = node.nodeDesc;
            _nodeOpin.signOpin = node.approvalOpition ? node.approvalOpition : '';
            _nodeOpin.signLabel = node.isStart ? '发起人' : '签批人';
            _nodeOpin.signName = node.handleUserName ? node.handleUserName : '';
            _nodeOpin.signDate = node.approvalTime ? node.approvalTime.split("-").join(".") : '';
            _nodeOpin.startDate = this.infoId && node.isStart && node.createTime ? node.createTime : '';
            if(node.xcoordinate + 15 < 244){
                _nodeOpin.posX = 0;
                _nodeOpin.arrowPosX = node.xcoordinate + 15 - 8;
            }else if(_attr.width - node.xcoordinate - 15 < 244){
                _nodeOpin.posX = _attr.width - 488;
                _nodeOpin.arrowPosX = node.xcoordinate - _nodeOpin.posX + 15 - 8;
            }else{
                _nodeOpin.posX = node.xcoordinate + 15 - 244;
                _nodeOpin.arrowPosX = 244 - 8;
            }
            _nodeOpin.posY = node.ycoordinate + 40;
            this.nodeOpin.show = true;
        },
        nodeApprOpinHide(){
            this.nodeOpin.show = false;
        }
    },
    components: {
        orgTree
    }
}
</script>
<style lang='scss' scoped>
    .work-flow{
        text-align: left;
    }
    .work-flow-main{
        position: relative;
        margin: 0 auto;
    }
    .work-flow-cavs{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 10;
    }
    .work-flow-list{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 20;
        .work-flow-item{
            position: absolute;
            top: 0;
            left: 0;
            width: 30px;
            height: 30px;
            .wkfl-item-audr{
                position: absolute;
                top: 0;
                left: -29px;
                width: 88px;
                padding: 3px 6px;
                .wfim-audr-text{
                    line-height: 16px;
                    max-height: 48px;
                    text-align: center;
                    font-size: 12px;
                    color: #6AB616;
                    overflow: hidden;
                }
            }
            .wkfl-item-node{
                width: 30px;
                height: 30px;
                padding: 6px;
                background: #fff;
                border-radius: 50%;
                cursor: pointer;
                .wfim-node-dot{
                    display: block;
                    width: 18px;
                    height: 18px;
                    background: #7ED321;
                    border-radius: 50%;
                }
            }
            .wkfl-item-type{
                position: absolute;
                bottom: -25px;
                left: -6px;
                width: 42px;
                height: 22px;
                line-height: 18px;
                padding-top: 4px;
                background: url('../../../../static/img/icon-bule-gren-42x22.png') 0 0 no-repeat;
                text-align: center;
                font-size: 12px;
                color: #8AD737;
                overflow: hidden;
            }
            &.gene.active .wkfl-item-audr{
                padding: 2px 5px;
                background: #FFFAB7;
                border: #F8E71C 1px solid;
                border-radius: 5px;
                .wfim-audr-text{
                    color: #D6C818;
                }
                &:before,&:after{
                    position: absolute;
                    left: 41px;
                    width: 0;
                    height: 0;
                    border-width: 3px;
                    border-style: dashed solid dashed dashed;
                    font-size: 0;
                    content: "";
                }
                &:before{
                    bottom: -7px;
                    border-color: #F8E71C transparent transparent transparent;
                    z-index: 10;
                }
                &:after{
                    bottom: -6px;
                    border-color: #FFFAB7 transparent transparent transparent;
                    z-index: 20;
                }
            }
            &.gene.active .wkfl-item-node{
                padding: 5px;
                border: #F8E71C 1px solid;
                .wfim-node-dot{
                    background: #F8E71C;
                }
            }
            &.gene.active .wkfl-item-type{
                background: url('../../../../static/img/icon-bule-yelw-42x22.png') 0 0 no-repeat;
                color: #D6C818;
            }
            &.start .wkfl-item-audr,&.end .wkfl-item-audr{
                top: -22px;
                padding: 0;
            }
            &.start.active .wkfl-item-audr .wfim-audr-text{
                color: #D6C818;
            }
            &.start.active .wkfl-item-node .wfim-node-dot{
                background: #F8E71C;
            }
            &.gene.is-pass .wkfl-item-node{
                padding: 5px;
                border: #B8E986 1px solid;
                .wfim-node-dot{
                    background: #7ED321 url('../../../../static/img/icon-right-white-10x8.png') center no-repeat;
                }
            }
            &.gene.not-pass .wkfl-item-audr .wfim-audr-text{
                color: #F4465B;
            }
            &.gene.not-pass .wkfl-item-node{
                padding: 5px;
                border: #FF97A4 1px solid;
                .wfim-node-dot{
                    background: #F4465B url('../../../../static/img/icon-close-white-6x6.png') center no-repeat;
                }
            }
            &.gene.not-pass .wkfl-item-type{
                background: url('../../../../static/img/icon-bule-red-42x22.png') 0 0 no-repeat;
                color: #FF97A4;
            }
            &.not-start .wkfl-item-audr .wfim-audr-text,&.not-impl .wkfl-item-audr .wfim-audr-text{
                color: #CACDCC;
            }
            &.not-start .wkfl-item-node .wfim-node-dot,&.not-impl .wkfl-item-node .wfim-node-dot{
                background: #CACDCC;
            }
            &.not-start .wkfl-item-type,&.not-impl .wkfl-item-type{
                background: url('../../../../static/img/icon-bule-gray-42x22.png') 0 0 no-repeat;
                color: #CFD2D1;
            }
        }
    }
    .wkfl-hdlr-list{
        padding: 0 25px;
        .wkfl-hdlr-item{
            height: 60px;
            line-height: 20px;
            padding: 20px 0;
            border-bottom: #ddd 1px dotted;
            overflow: hidden;
            .wfhd-item-name{
                float: left;
                margin-right: 10px;
                font-size: 16px;
                color: #4A4A4A;
            }
            .wfhd-item-hdlr{
                float: left;
                width: 120px;
                height: 20px;
                line-height: 20px;
                border: 0;
                outline: 0;
                font-size: 16px;
                color: #2C8DF1;
            }
            .wfhd-item-sel{
                float: right;
                width: 20px;
                height: 20px;
                background: url('../../../../static/img/icon-plus-bgw-20x20.png') 0 0 no-repeat;
                cursor: pointer;
            }
        }
    }
    .wkfl-hdlr-end{
        height: 60px;
        line-height: 20px;
        padding: 20px 25px;
        border-bottom: #e9eaec 1px solid;
        font-size: 16px;
        color: #4A4A4A;
    }
    .wkfl-hdlr-oper{
        height: 46px;
        padding: 10px 2px 10px 0;
        overflow: hidden;
        .save,.cancel{
            float: right;
            width: 60px;
            height: 26px;
            line-height: 26px;
            margin-right: 12px;
            border-radius: 3px;
            text-align: center;
            font-size: 14px;
            cursor: pointer;
        }
        .save{
            background: #2A96D8;
            border: #1B618F 1px solid;
            color: #fff;
            &:hover{
                background: #257DBA;
            }
        }
        .cancel{
            background: #fff;
            border: #9D9D9D 1px solid;
            color: #171717;
            &:hover{
                background: #F1F1F1;
            }
        }
    }
    .work-flow-opin{
        position: absolute;
        top: 0;
        left: 0;
        width: 488px;
        padding-top: 8px;
        pointer-events: none;
        z-index: 30;
        .wkfl-opin-main{
            padding: 13px 30px 13px 22px;
            background: #fff;
            border: #8AD737 1px solid;
            border-radius: 5px;
            .wkfl-opin-title{
                height: 22px;
                line-height: 22px;
                font-weight: bold;
                font-size: 14px;
                color: #3E4D63;
                span{
                    font-weight: normal;
                    font-size: 12px;
                    color: #a1a1a1;
                }
            }
            .wkfl-opin-signr,.wkfl-opin-start{
                height: 26px;
                line-height: 26px;
                font-size: 14px;
                color: #3E4D63;
            }
            .wkfl-opin-ctnt{
                line-height: 26px;
                margin-top: 5px;
                padding-left: 8px;
                text-indent: 2em;
                font-size: 14px;
                color: #4A4A4A;
                overflow: hidden;
                word-break: break-all;
            }
            .wkfl-opin-info{
                height: 28px;
                line-height: 28px;
                text-align: right;
                font-weight: bold;
                font-size: 14px;
                color: #3E4D63;
                span{
                    font-size: 22px;
                    &.date{
                        margin-right: 15px;
                        font-family: 'DINCondensed-Bold';
                        font-weight: normal;
                    }
                }
            }
        }
        .wkfl-opin-close{
            position: absolute;
            top: 16px;
            right: 8px;
            width: 10px;
            height: 10px;
            background: url('../../../../static/img/icon-close-gray-10x10.png') 0 0 no-repeat;
            cursor: pointer;
        }
        .wkfl-opin-arrow{
            position: absolute;
            left: 0;
            width: 0;
            height: 0;
            border-width: 8px;
            border-style: dashed dashed solid dashed;
            font-size: 0;
            &.top{
                top: -7px;
                border-color: transparent transparent #fff transparent;
                z-index: 20;
            }
            &.bottom{
                top: -8px;
                border-color: transparent transparent #8AD737 transparent;
                z-index: 10;
            }
        }
    }
</style>
<style lang='scss'>
    .work-flow-dlog{
        .ivu-modal-body{
            padding: 0;
        }
        .ivu-modal-footer{
            padding: 0;
            border-top: 0;
        }
    }
</style>
